package log

import (
	"errors"
	"os"
	"time"

	"go-fast/pkg/config"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

// InitLogger 初始化日志配置
func InitLogger(conf *config.LogConfig) (*zap.SugaredLogger, error) {
	if conf == nil {
		return nil, errors.New("not init config")
	}

	encoderConfig := zapcore.EncoderConfig{
		MessageKey:   "msg",                       //结构化（json）输出：msg的key
		LevelKey:     "level",                     //结构化（json）输出：日志级别的key（INFO，WARN，ERROR等）
		TimeKey:      "ts",                        //结构化（json）输出：时间的key（INFO，WARN，ERROR等）
		CallerKey:    "file",                      //结构化（json）输出：打印日志的文件对应的Key
		EncodeLevel:  zapcore.CapitalLevelEncoder, //将日志级别转换成大写（INFO，WARN，ERROR等）
		EncodeCaller: zapcore.ShortCallerEncoder,  //采用短文件路径编码输出（test/main.go:14 ）
		EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
			enc.AppendString(t.Format("2006-01-02 15:04:05"))
		}, //输出的时间格式
		EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
			enc.AppendInt64(int64(d) / 1000000)
		}, //
	}
	encoder := zapcore.NewConsoleEncoder(encoderConfig)

	// 日志存储配置
	hook := lumberjack.Logger{
		Filename:   conf.LogPath, // 日志文件路径，默认 os.TempDir()
		MaxSize:    conf.MaxSize, // 每个日志文件保存10M，默认 100M
		MaxBackups: 30,           // 保留30个备份，默认不限
		MaxAge:     7,            // 保留7天，默认不限
		Compress:   false,        // 是否压缩，默认不压缩
	}

	// 设置日志级别
	logLevel := zapcore.Level(conf.Level)

	// 设置日志文件安info和error文件分开输出
	////自定义日志级别：自定义Info级别
	//infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
	//	return lvl < zapcore.WarnLevel && lvl >= logLevel
	//})
	//
	////自定义日志级别：自定义Warn级别
	//warnLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
	//	return lvl >= zapcore.WarnLevel && lvl >= logLevel
	//})
	//// 获取io.Writer的实现
	//infoWriter := getWriter(logPath)
	//warnWriter := getWriter(errPath)
	//// 实现多个输出
	//core := zapcore.NewTee(
	//	zapcore.NewCore(zapcore.NewConsoleEncoder(encoderConfig), zapcore.AddSync(infoWriter), infoLevel), //将info及以下写入logPath，NewConsoleEncoder 是非结构化输出
	//	zapcore.NewCore(zapcore.NewConsoleEncoder(encoderConfig), zapcore.AddSync(warnWriter), warnLevel),//warn及以上写入errPath
	//	zapcore.NewCore(zapcore.NewJSONEncoder(encoderConfig), zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout)), logLevel),//同时将日志输出到控制台，NewJSONEncoder 是结构化输出
	//)

	var writeSyncer zapcore.WriteSyncer
	// 设置是否输出到控制台
	if conf.Stdout {
		writeSyncer = zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook))
	} else {
		writeSyncer = zapcore.AddSync(&hook)
	}

	core := zapcore.NewCore(encoder, writeSyncer, logLevel)
	// zap.AddCaller()  添加将调用函数信息记录到日志中的功能。
	logger := zap.New(core, zap.AddCaller())

	return logger.Sugar(), nil
}

//func getWriter(filename string) io.Writer {
//	// 生成rotatelogs的Logger 实际生成的文件名 filename.YYmmddHH
//	// filename是指向最新日志的链接
//	hook := &lumberjack.Logger{
//		Filename: filename+".%Y%m%d%H",
//		MaxSize:    512, // megabytes
//		MaxBackups: 3,
//		MaxAge:     30,   // days
//		Compress:   true, // disabled by default
//	}
//	return hook
//}
